package com.theatre.userservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.theatre.userservice.mapper.*;
import com.theatre.userservice.model.dto.MenuDTO;
import com.theatre.userservice.model.dto.RoleDTO;
import com.theatre.userservice.model.entity.*;
import com.theatre.userservice.model.vo.FunctionVO;
import com.theatre.userservice.model.vo.MenuVO;
import com.theatre.userservice.model.vo.RoleVO;
import com.theatre.userservice.service.MenuService;
import com.theatre.userservice.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Slf4j
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private RoleFunctionMapper roleFunctionMapper;
    @Autowired
    private FunctionMapper functionMapper;
    @Autowired
    private MenuService menuService;

    /**
     * 新增角色
     */
    @Override
    @Transactional
    public void addRole(RoleDTO roleDTO) {
        Role role = new Role();
        role.setName(roleDTO.getName());
        role.setDescription(roleDTO.getDescription());
        baseMapper.insert(role);

        Long roleId = role.getId(); // MP 会自动回写主键

        // 插入功能关系
        if (roleDTO.getFunctionIds() != null) {
            for (Long functionId : roleDTO.getFunctionIds()) {
                RoleFunction rf = new RoleFunction();
                rf.setRoleId(roleId);
                rf.setFunctionId(functionId);
                roleFunctionMapper.insert(rf);
            }
        }

        // 插入菜单关系
        if (roleDTO.getMenuIds() != null) {
            for (MenuDTO menuDTO : roleDTO.getMenuIds()) {
                insertMenuRecursively(roleId, menuDTO);
            }
        }
    }

    /**
     * 根据 ID 查询角色详情
     */
    @Override
    @Transactional(readOnly = true)
    public RoleVO selectById(Long id) {
        Role role = baseMapper.selectById(id);
        if (role == null) {
            return null;
        }

        RoleVO roleVO = new RoleVO();
        roleVO.setId(role.getId());
        roleVO.setName(role.getName());
        roleVO.setDescription(role.getDescription());

        // 查询功能列表
        List<Long> functionIds = roleFunctionMapper.selectList(
                new QueryWrapper<RoleFunction>().eq("role_id", id)
        ).stream().map(RoleFunction::getFunctionId).toList();

        if (!functionIds.isEmpty()) {
            List<Function> functions = functionMapper.selectList(
                    new QueryWrapper<Function>().in("id", functionIds)
            );
            List<FunctionVO> functionVOs = functions.stream().map(func -> {
                FunctionVO vo = new FunctionVO();
                vo.setId(func.getId());
                vo.setName(func.getName());
                vo.setDescription(func.getDescription());
                return vo;
            }).toList();
            roleVO.setFunctionIds(functionVOs);
        }

        // 查询菜单树
        List<MenuVO> menuVOList = menuService.selectMenusByRoleId(id);
        roleVO.setMenuIds(menuVOList);

        return roleVO;
    }

    /**
     * 修改角色信息及其关联（菜单 + 功能）
     */
    @Override
    @Transactional
    public void updateById(RoleDTO roleDTO) {
        if (roleDTO.getId() == null) {
            throw new IllegalArgumentException("角色ID不能为空");
        }

        Long roleId = roleDTO.getId();

        // 1. 更新角色基础信息
        Role role = new Role();
        role.setId(roleId);
        role.setName(roleDTO.getName());
        role.setDescription(roleDTO.getDescription());
        baseMapper.updateById(role);

        // 2. 清空旧关联
        roleFunctionMapper.delete(new QueryWrapper<RoleFunction>().eq("role_id", roleId));
        roleMenuMapper.delete(new QueryWrapper<RoleMenu>().eq("role_id", roleId));

        // 3. 重新插入功能关联
        if (roleDTO.getFunctionIds() != null) {
            for (Long functionId : roleDTO.getFunctionIds()) {
                RoleFunction rf = new RoleFunction();
                rf.setRoleId(roleId);
                rf.setFunctionId(functionId);
                roleFunctionMapper.insert(rf);
            }
        }

        // 4. 重新插入菜单关联
        if (roleDTO.getMenuIds() != null) {
            for (MenuDTO menuDTO : roleDTO.getMenuIds()) {
                insertMenuRecursively(roleId, menuDTO);
            }
        }

        log.info("角色 [{}] 更新完成", roleDTO.getName());
    }
    @Override
    @Transactional
    public void deleteById(Long roleId) {
        if (roleId == null) {
            throw new IllegalArgumentException("角色ID不能为空");
        }

        // 1. 删除角色与功能的关联
        int funcDeleted = roleFunctionMapper.delete(
                new QueryWrapper<RoleFunction>().eq("role_id", roleId)
        );

        // 2. 删除角色与菜单的关联
        int menuDeleted = roleMenuMapper.delete(
                new QueryWrapper<RoleMenu>().eq("role_id", roleId)
        );

        // 3. 删除角色本身
        int roleDeleted = baseMapper.deleteById(roleId);

        if (roleDeleted == 0) {
            throw new RuntimeException("角色删除失败：角色不存在");
        }

        log.info("删除角色成功：id={}, 删除功能关联 {} 条, 删除菜单关联 {} 条", roleId, funcDeleted, menuDeleted);
    }
    /**
     * 递归插入树形菜单到角色菜单关联表
     */
    private void insertMenuRecursively(Long roleId, MenuDTO menuDTO) {
        if (menuDTO == null) return;

        RoleMenu rm = new RoleMenu();
        rm.setRoleId(roleId);
        rm.setMenuId(menuDTO.getId());
        roleMenuMapper.insert(rm);

        if (menuDTO.getChildren() != null && !menuDTO.getChildren().isEmpty()) {
            for (MenuDTO child : menuDTO.getChildren()) {
                insertMenuRecursively(roleId, child);
            }
        }
    }
}
